package com.xhb.campusservices.shiro;

import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xhb.campusservices.common.lang.ResultCode;
import com.xhb.campusservices.pojo.User;
import com.xhb.campusservices.service.UserService;
import com.xhb.campusservices.util.JWTUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;

public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;

    /**
     * 限定这个realm只能处理JwtToken
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    /**
     * 授权(授权部分这里就省略了)
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        authorizationInfo.addStringPermission(user.getUsername());
        return authorizationInfo;
    }

    /**
     * 根据token进行登陆验证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //JwtToken中重写了这个方法了
        // 这里的 token是从 JwtFilter 的 executeLogin 方法传递过来的，已经经过了解密
        String token = (String) authenticationToken.getCredentials();

        User user = userService.getById(JWTUtils.getUserId(token));
        if (user == null) {
            //设置401状态码
            new ResultCode().setCode(ResultCode.USER_NOT_EXIST);
            throw new AccountException("账号不存在!!");
        }

        if (JWTUtils.isExpire(token)) {
            //设置403状态码
            new ResultCode().setCode(ResultCode.PERMISSION_NO_ACCESS);
            throw new AuthenticationException("token过期，请重新登入!!");
        }
        return new SimpleAuthenticationInfo(user,token,this.getName());
    }

}
